package com.fjzx.androidframe.base.fragment;

import android.arch.lifecycle.ViewModel;
import android.arch.lifecycle.ViewModelProviders;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.View;

import com.fjzx.androidframe.base.annotation.injector.ViewModelInjector;
import com.fjzx.androidframe.global.entity.Resource;


/**
 * 基础Fragment类
 *
 * @param <VM> ViewModel
 * @author xiongyongcong
 */
public abstract class BaseFragment<VM extends ViewModel> extends BaseSimpleFragment {
    /**
     * ViewModel实例
     */
    protected VM mViewModel;

    protected boolean isViewInitiated;
    protected boolean isVisibleToUser;
    protected boolean isDataLoaded;

    protected boolean isLazyLoad() {
        return false;
    }

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        this.isVisibleToUser = isVisibleToUser;
        if (isLazyLoad()) {
            startloadData();
        }
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        this.isViewInitiated = true;
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        if (isLazyLoad()) {
            startloadData();
        } else {
            initViewModel();
            initData();
        }
    }

    protected void startloadData() {
        if (this.isVisibleToUser && this.isViewInitiated && !isDataLoaded) {
            initViewModel();
            initData();
            this.isDataLoaded = true;
        }
    }

    /**
     * 初始化ViewModel
     */
    protected void initViewModel() {
        // 获取ViewModel
        if (mViewModel == null) {
            mViewModel = ViewModelProviders.of(this).get(ViewModelInjector.inject(this));
        }
    }

    /**
     * ViewModel 回调
     *
     * @param resource
     */
    protected void handleResult(Resource<?> resource) {
        switch (resource.status) {
            case LOADING:
                handleLoading(resource.action, resource.loadingMsgId);
                break;
            case ERROR:
                handleError(resource.action, resource.errorMessage);
                break;
            case SUCCESS:
                handleSuccess(resource.action, resource.data);
                break;
            default:
                break;
        }
    }

    /**
     * ViewModel 错误回调
     *
     * @param action
     * @param message
     */
    protected void handleError(String action, String message) {
        hideProgress();
        showToast(message);
    }

    /**
     * ViewModel 加载中回调
     *
     * @param action
     * @param msgId
     */
    protected void handleLoading(String action, int msgId) {
        showProgress(msgId > 0 ? getString(msgId) : null);
    }

    /**
     * ViewModel 成功回调
     *
     * @param action
     * @param data
     */
    protected <T> void handleSuccess(String action, T data) {
        hideProgress();
    }

    /** ----------------  抽象方法  --------------------- **/

    /**
     * 子类重写该方法，初始化View
     *
     * @param view 根布局View
     */
    @Override
    abstract protected void initView(View view);

    /**
     * 子类重写该方法，请求数据
     */
    abstract protected void initData();

}
